<script lang="ts" setup>
import { computed, reactive, ref, watch } from 'vue'
import type { FormInstance } from 'ant-design-vue/es/form'
import type { FilterItem, SearchFilterEmits, SearchFilterProps } from './typing'

const props = withDefaults(defineProps<SearchFilterProps>(), {
  labelWidth: '80px',
  inline: true,
  maxRow: 1,
})

const emit = defineEmits<SearchFilterEmits>()

const collapsed = ref(false)

// 表单实例
const formRef = ref<FormInstance>()

// 表单数据
const formData = reactive<Record<string, any>>({})

// 初始化默认值
watch(() => props.filters, (filters) => {
  filters.forEach((item) => {
    if (item.defaultValue !== undefined) {
      formData[item.field] = item.defaultValue
    }
  })
}, { immediate: true })

// 计算显示的筛选项
const displayFilters = computed(() => {
  if (!props.collapsed)
    return props.filters
  const itemsPerRow = 3
  return props.filters.slice(0, props.maxRow * itemsPerRow)
})

// 获取表单项样式
function getItemStyle(item: FilterItem) {
  return {
    width: item.width ? `${item.width}px` : '200px',
  }
}

// 搜索
async function handleSearch() {
  try {
    await formRef.value?.validate()
    emit('search', formData)
  }
  catch (error) {
    // 表单验证失败
  }
}

// 重置
function handleReset() {
  formRef.value?.resetFields()
  emit('reset')
}
</script>

<template>
  <div class="search-filter">
    <a-form
      ref="formRef"
      :model="formData"
      :label-col="{ style: { width: labelWidth } }"
      :layout="inline ? 'inline' : 'horizontal'"
    >
      <template v-for="item in displayFilters" :key="item.field">
        <a-form-item
          :label="item.label"
          :name="item.field"
          :rules="item.rules"
        >
          <!-- 输入框 -->
          <a-input
            v-if="item.type === 'input'"
            v-model:value="formData[item.field]"
            :placeholder="item.placeholder as string || '请输入'"
            :style="getItemStyle(item)"
            allow-clear
            @press-enter="handleSearch"
          />

          <!-- 选择框 -->
          <a-select
            v-else-if="item.type === 'select'"
            v-model:value="formData[item.field]"
            :placeholder="item.placeholder"
            :style="getItemStyle(item)"
            allow-clear
          >
            <a-select-option
              v-for="option in item.options"
              :key="option.value"
              :value="option.value"
              :disabled="option.disabled"
            >
              {{ option.label }}
            </a-select-option>
          </a-select>

          <!-- 日期选择 -->
          <a-date-picker
            v-else-if="item.type === 'datePicker'"
            v-model:value="formData[item.field]"
            :placeholder="item.placeholder as string || '请选择日期'"
            :style="getItemStyle(item)"
          />

          <!-- 日期范围选择 -->
          <a-range-picker
            v-else-if="item.type === 'rangePicker'"
            v-model:value="formData[item.field]"
            :placeholder="item?.placeholder as string[] || ['开始日期', '结束日期']"
            :style="getItemStyle(item)"
          />
        </a-form-item>
      </template>

      <!-- 操作按钮 -->
      <a-form-item>
        <a-space>
          <a-button type="primary" @click="handleSearch">
            搜索
          </a-button>
          <a-button @click="handleReset">
            重置
          </a-button>
          <a-button
            v-if="filters.length > maxRow * 3"
            type="link"
            @click="() => collapsed = !collapsed"
          >
            {{ collapsed ? '展开' : '收起' }}
            <!-- <template #icon>
              <down-outlined v-if="collapsed" />
              <up-outlined v-else />
            </template> -->
          </a-button>
        </a-space>
      </a-form-item>
    </a-form>
  </div>
</template>

<style lang="less" scoped>
.search-filter {
  padding: 16px;
  border-radius: 2px;
}
</style>
